#pragma once

#include "error.h"
#include "opencv2/opencv.hpp"
#include <string>
#include <Windows.h>
#include <filesystem>
#include <stdarg.h>
#include <vector>
#ifndef slLog
#define slLog Log::getInstance()
#endif

using namespace cv;
namespace fs = std::filesystem;
namespace SL
{
    namespace io
    {
        void createFolder(std::string folder)
        {
            if (!fs::exists(folder))
            {
                fs::create_directories(folder);
            }
        }

        bool isFolderExist(std::string folder)
        {
            return fs::exists(folder);
        }

        std::string getFilenameFromPath(std::string path, bool extension = false)
        {
            std::string baseFilename = path.substr(path.find_last_of("/\\") + 1);
            std::string::size_type const p(baseFilename.find_last_of('.'));
            std::string baseFilenameWithoutExtension = baseFilename.substr(0, p);
            return extension ? baseFilename : baseFilenameWithoutExtension;
        }

        // template <typename... Args>
        // void joinPath(const Args... args)
        // {
        //     std::cout << sizeof(args) << std::endl;
        // }

        template <typename... Args>
        std::string joinPath(Args const &...args)
        {
            int size = sizeof...(Args);
            std::vector<std::string> vec = {args...};
            std::string res;
            for (int i = 0; i < size; i++)
            {
                res += (i == 0 ? "" : "\\") + vec[i];
            }
            return res;
            // std::ostringstream stream;
            // int x[] = {0, ((void)(stream << args), 0)...};
            // return stream.str();
        }

        // std::string joinPath(int n, std::string t...)
        // {
        //     std::cout << typeid(int).name() << std::endl;
        //     va_list arg_ptr;
        //     va_start(arg_ptr, n);
        //     std::string res;
        //     for (int i = 0; i < n; i++)
        //     {
        //         res += va_arg(arg_ptr, std::string);
        //     }
        //     va_end(arg_ptr);
        //     return res;
        // }

        // template <class T>
        // T add(int n, T t...)
        // {
        //     const std::size_t n = sizeof...(T);
        //     std::cout << typeid(T).name() << std::endl;
        //     va_list arg_ptr;
        //     va_start(arg_ptr, n);
        //     T res(0);
        //     for (int i = 0; i < n; i++)
        //     {
        //         res += va_arg(arg_ptr, T);
        //     }
        //     va_end(arg_ptr);
        //     // cout << res << endl;
        //     return res;
        // }
    }
}